/***************************************************************\
 * Пример telnet эхо сервера с использованием библиотеки lampe  *
 *                                                              *
 * При компиляции нужно помнить, что для Windows нужно          *
 * использовать библиотеку ws2_32 что бы обеспечить работу с    *
 * сетью. Для Linux необходимо использовать библиотеку pthread, *
 * что бы обеспечить работу с потоками. Так уж сложилось, что   *
 * работа с потоками в Windows работает из коробки, а сеть нет. *
 * А в Linux наобарот.                                          *
 \***************************************************************/

 
#include <stdio.h>
#include <lampe/network/tcp/ITCPServer.h>
#include <lampe/network/IClient.h>

lampe::network::ITCPServer*tcp=0;

/**
 * @class TelnetClient
 * Наш класс, отвечающий за обработку подключенного клиента
 */
class TelnetClient:public lampe::network::IClientCallback{
private:
	//!объект клиента
	lampe::network::IClient*client;
public:

	/**
	 * Вызовется тогда, когда клиент будет готов. Передаст нам каким
	 * именно клиентом управляет наш класс
	 */
	virtual void ready(lampe::network::IClient*c){
		client=c;//запоминаем. Пригодится
	}

	/**
	 * Вызовется тогда, когда придёт время читать из потока данных.
	 */
	virtual void readData(){
		while (!client->getReader()->eof()){//пока есть что читать
			lampe::String cmd=client->getReader()->readLine();//считываем строку (т.е. до знака переноса. Всё как положено). Выполнение остановится пока клиент что-то не передаст нам
			if (cmd=="exit" || cmd=="quit")
				return;
			if (cmd=="stop")
				tcp->stop();
			printf("Getted \"%s\"\n",cmd.c_str());//выводим сообщение, о том, что клиент нам что-то передал
			client->getWriter()->writeLine(cmd);//отправляем клиенту то что он нам написал
		}
	}
	/**
	 * Вызовется тогда, когда клиент подключится
	 */
	virtual void onConnected(){
		printf("Client connected!\n");//пишем сообщение
		client->getWriter()->writeLine("Hi User!");//Здароваемся с пользователем
		client->getWriter()->writeLine("write cmd \"exit\" or \"quit\" for close connect");
		client->getWriter()->writeLine("write cmd \"stop\" for stop server");
	}

	/**
	 * Вызовется тогда, когда клиент отключится
	 */
	virtual void onDisconnected(){
		printf("Client disconnected!\n");//пишим сообщение
	}
};

class TelnetServer:public lampe::network::IServerCallBack{
public:
	/**
	 * Вызовется тогда, когда потребуется вернуть управляющий класс для нового
	 * клента. Обычно вызывается при подключении нового клиента
	 */
	virtual lampe::network::IClientCallback*giveClientCallback(){
		return new TelnetClient();//создаём наш управляющий класс и возвращяем его
	}
};

int main() {
	TelnetServer*t=new TelnetServer();//управляющий сервером класс
	tcp=lampe::network::createTCPServer(t);//создаём TCP сервер
	t->drop();//управляющий сервером объект нам больше не нужен
	tcp->port(80);//указываем порт сервера
	tcp->start();//запускаем сервер
	tcp->wait();//ждём завершения работы сервера
	tcp->drop();//избавляемся от tcp сервера
	return 0;
}
